package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;

/**
 * @author: yanming.wang
 * @date: 2024-02-27
 * @desp: 开启swagger配置, 必须新建此配置类, 并且添加@EnableSwagger2,否则报错:Unable to infer base url.
 * This is common when using dynamic servlet registration or when the API is behind an API Gateway.
 * The base url is the root of where all the swagger resources are served. For e.g.
 * if the api is available at http://example.org/api/v
 * <p>
 * Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件。
 * Swagger 是一个规范和完整的框架，用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。
 * 总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法，参数和模型紧密集成到服务器端的代码，允许API来始终保持同步。
 * Swagger让部署管理和使用功能强大的API从未如此简单。
 */
@Configuration
@EnableSwagger2
public class Swagger2Config {

    /**
     * 配置swagger的docket实例
     *
     * @return
     */
    @Bean
    public Docket getDocket(Environment environment) {
        String name = "WangYanMing";
        String url = "https://gitee.com/wangym2chenx/nacos";
        String email = "wangyanming131@126.com";
        String chineseName = "王艳明";
        String groupName = "WangYanMing";
        String packageName = "yanming";

        Docket docket = docket(name, url, email, chineseName, environment, groupName, packageName);

        return docket;

    }

    @Bean
    public Docket getDocket2(Environment environment) {


        String name = "ChenXue";
        String url = "https://gitee.com/wangym2chenx/nacos";
        String email = "wangyanming131@163.com";
        String chineseName = "陈雪";
        String groupName = "ChenXue";
        String packageName = "chenxue";

        Docket docket = docket(name, url, email, chineseName, environment, groupName, packageName);
        return docket;
    }


    /**
     * 配置swagger,自定义作者信息
     *
     * @return
     */
    private ApiInfo apiInfo(String name, String url, String email, String chineseName) {
        Contact contact = new Contact(name, url, email);

        String title = chineseName + "的SwaggerAPI文档";
        String description = "bigdata项目实战";
        String version = "v1.0";
        String termsOfServiceUrl = url;

        String license = "Apache2.0";
        String licenseUrl = "https://www.apache.org/licenses/LICENSE-2.0";
        return new ApiInfo(title, description,
                version, termsOfServiceUrl,
                contact, license, licenseUrl, new ArrayList<>());

    }

    /**
     * 提前docket共用代码
     * swagger分组
     * 在swagger配置时可分为不同的多个Docket对象，相当于每一个Docket对象就是一个项目中的开发者。
     * 可以设置多个ApiInfo信息，再通过Docket的groupName()
     * 参数为ApiInfo中Contact对象的name成员变量，在上面我们知道了Docket中可以设置扫描接口，
     * 那我们在通过扫描不同的接口、配置不同的ApiInfo信息，那么就可以进行swagger的分组(就可以在swagger中区别不同开发者写的接口及代码)
     *
     * @return
     */
    private Docket docket(String name, String url, String email, String chineseName, Environment environment,
                          String groupName, String packageName) {
        Docket docket = new Docket(DocumentationType.SWAGGER_2);

        // 配置作者信息
        docket = docket.apiInfo(apiInfo(name, url, email, chineseName));

        // 设置需要显示的环境


        /*
            方便我们测试所以创建多个SpringBoot的配置文件properties，在主配置文件中配置spring.profiles.active=具体配置环境(代表当前项目使用的是那一个项目环境)

        1.设置需要显示的swagger环境(例如：只有在dev或者test环境下才显示)：Profiles profiles =Profiles.of(“dev”,“test”);
        2.判断当前环境是否为设置的环境(返回boolean值true或false)：boolean flag = environment.acceptsProfiles(profiles);
        3.将flag变量传到Docket实例的.enable(flag)属性中：enable(flag)*/


        // 至此就可以通过获取当前环境而控制swagger的访问
        Profiles profiles = Profiles.of("dev", "test");
        boolean flag = environment.acceptsProfiles(profiles);

        // 配置swagger扫描接口
        docket.groupName(groupName) //swagger信息(ApiInfo)中的name成员变量(不同的开发者信息就需要设置多个ApiInfo在不同的Docket实例中获取)
                // .enable(false)：是否启用swagger  如果为false,浏览器中不能访问(默认为true)
                .enable(flag)
                .select()
                /*RequestHandlerSelectors：配置扫描接口的方式
                 * basePackage：指定扫描的包
                 * any：扫描全部
                 * none：不扫描
                 * withClassAnnotation：扫描类上的注解，参数为一个注解的反射对象
                 * withMethodAnnotation：扫描方法上的注解*/
                .apis(RequestHandlerSelectors.basePackage("com.example.demo.swagger." + packageName))
                /*paths()：过滤路径*/
                // .paths(PathSelectors.ant("/action"))
                .build();

        return docket;
    }


}
